package com.fengyi.library.controller;

import com.fengyi.library.DTO.BookDTO;
import com.fengyi.library.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

/**
 * OpenFeign测试控制器
 * 用于测试OpenFeign功能
 * 根据Accept头判断返回HTML或JSON
 */
@Controller
@RequestMapping("/api/feign-test")
public class OpenFeignTestController {

    @Value("${server.port}")
    private String serverPort;

    @Autowired
    private BookService bookService;

    /**
     * 测试OpenFeign调用
     * 如果Accept头包含text/html，返回HTML页面
     * 否则返回JSON数据
     * 
     * @param keyword 搜索关键字，默认为"Java"
     * @param timeout 是否模拟超时
     * @param retry 是否启用重试
     * @param model 模型（用于HTML视图）
     * @return 视图名或JSON数据
     */
    @GetMapping(produces = MediaType.TEXT_HTML_VALUE)
    public String testOpenFeignHtml(
            @RequestParam(required = false, defaultValue = "Java") String keyword,
            @RequestParam(required = false, defaultValue = "false") boolean timeout,
            @RequestParam(required = false, defaultValue = "false") boolean retry,
            Model model) {
        
        // 添加模型属性，用于Thymeleaf模板
        model.addAttribute("currentPort", serverPort);
        model.addAttribute("message", "OpenFeign测试 - 当前服务运行在端口: " + serverPort);
        model.addAttribute("timeout", timeout);
        model.addAttribute("retry", retry);
        
        // 输出当前端口号到控制台
        System.out.println("********************************************");
        System.out.println("* OpenFeign测试(HTML) - 端口 " + serverPort + " 收到请求 *");
        System.out.println("* 搜索关键字: " + keyword + " *");
        System.out.println("********************************************");
        
        // 返回Thymeleaf视图
        return "openfeign-test";
    }

    /**
     * 测试OpenFeign调用 - JSON响应
     * 
     * @param keyword 搜索关键字，默认为"Java"
     * @return JSON数据
     */
    @GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE, "*/*"})
    @ResponseBody
    public Map<String, Object> testOpenFeignJson(
            @RequestParam(required = false, defaultValue = "Java") String keyword) {
        
        Map<String, Object> result = new HashMap<>();
        
        // 添加当前服务信息
        result.put("currentPort", serverPort);
        result.put("message", "OpenFeign测试 - 当前服务运行在端口: " + serverPort);
        
        // 输出当前端口号到控制台
        System.out.println("********************************************");
        System.out.println("* OpenFeign测试(JSON) - 端口 " + serverPort + " 收到请求 *");
        System.out.println("* 搜索关键字: " + keyword + " *");
        System.out.println("********************************************");
        
        // 通过本地服务调用图书查询API
        try {
            Pageable pageable = PageRequest.of(0, 10); // 第一页，每页10条
            Page<BookDTO> bookPage = bookService.searchBooks(keyword, pageable);
            result.put("feignCallResult", bookPage.getContent());
            result.put("count", bookPage.getTotalElements());
            result.put("status", "success");
            result.put("keyword", keyword);
            
            System.out.println("* 本地服务调用成功，返回 " + bookPage.getContent().size() + " 本图书 *");
            
            // 检查是否有结果
            if (bookPage.getTotalElements() == 0) {
                System.out.println("* 警告：未找到匹配关键词 \"" + keyword + "\" 的图书 *");
                result.put("warning", "未找到匹配关键词 \"" + keyword + "\" 的图书");
            }
        } catch (Exception e) {
            Map<String, String> errorInfo = new HashMap<>();
            errorInfo.put("error", "本地服务调用失败: " + e.getMessage());
            result.put("feignCallResult", errorInfo);
            result.put("status", "error");
            
            // 在控制台打印详细的异常信息
            System.out.println("* 本地服务调用失败: " + e.getMessage() + " *");
            System.out.println("* 异常类型: " + e.getClass().getName() + " *");
            e.printStackTrace(); // 打印完整堆栈信息
        }
        
        return result;
    }
    
    /**
     * 测试根据ID查询图书
     * @param id 图书ID，默认为1
     * @return 图书信息
     */
    @GetMapping(value = "/book", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> getBookById(
            @RequestParam(required = false, defaultValue = "1") Integer id) {
        
        Map<String, Object> result = new HashMap<>();
        
        // 添加当前服务信息
        result.put("currentPort", serverPort);
        result.put("message", "OpenFeign测试 - 查询图书 - 当前服务运行在端口: " + serverPort);
        
        // 输出当前端口号到控制台
        System.out.println("********************************************");
        System.out.println("* OpenFeign测试 - 查询图书 - 端口 " + serverPort + " 收到请求 *");
        System.out.println("* 图书ID: " + id + " *");
        System.out.println("********************************************");
        
        // 通过本地服务调用图书查询API
        try {
            BookDTO book = bookService.findById(id);
            if (book != null) {
                result.put("book", book);
                result.put("status", "success");
                
                System.out.println("* 本地服务调用成功，返回图书: " + book.getTitle() + " *");
            } else {
                // 图书不存在的情况
                Map<String, String> errorInfo = new HashMap<>();
                errorInfo.put("error", "图书不存在");
                errorInfo.put("id", id.toString());
                result.put("book", errorInfo);
                result.put("status", "not_found");
                
                System.out.println("* 图书不存在，ID: " + id + " *");
            }
        } catch (Exception e) {
            Map<String, String> errorInfo = new HashMap<>();
            errorInfo.put("error", "本地服务调用失败: " + e.getMessage());
            errorInfo.put("id", id.toString());
            result.put("book", errorInfo);
            result.put("status", "error");
            
            // 在控制台打印详细的异常信息
            System.out.println("* 本地服务调用失败: " + e.getMessage() + " *");
            System.out.println("* 异常类型: " + e.getClass().getName() + " *");
            System.out.println("* 图书ID: " + id + " *");
            e.printStackTrace(); // 打印完整堆栈信息
        }
        
        return result;
    }
    
    /**
     * 测试查询不存在的图书
     * 特意测试错误情况的处理
     */
    @GetMapping(value = "/test-not-exist", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> testNotExistBook() {
        // 使用一个不存在的ID
        final int nonExistentId = 9999;
        
        Map<String, Object> result = new HashMap<>();
        
        // 添加当前服务信息
        result.put("currentPort", serverPort);
        result.put("message", "OpenFeign测试 - 查询不存在的图书 - 当前服务运行在端口: " + serverPort);
        result.put("testCase", "故意查询不存在的图书(ID: " + nonExistentId + ")");
        
        // 输出当前端口号到控制台
        System.out.println("********************************************");
        System.out.println("* OpenFeign测试 - 查询不存在图书 - 端口 " + serverPort + " 收到请求 *");
        System.out.println("* 测试用例: 故意查询不存在的图书 *");
        System.out.println("* 图书ID: " + nonExistentId + " *");
        System.out.println("********************************************");
        
        // 通过本地服务调用图书查询API
        try {
            BookDTO book = bookService.findById(nonExistentId);
            
            // 如果没有抛出异常但返回null
            if (book == null) {
                Map<String, String> errorInfo = new HashMap<>();
                errorInfo.put("error", "图书不存在");
                errorInfo.put("id", String.valueOf(nonExistentId));
                result.put("book", errorInfo);
                result.put("status", "not_found");
                
                System.out.println("* 测试成功: 图书不存在返回null *");
                System.out.println("* 图书ID: " + nonExistentId + " *");
            } else {
                // 意外情况：不存在的ID实际返回了图书
                result.put("book", book);
                result.put("status", "unexpected_success");
                result.put("warning", "预期图书不存在，但实际找到了图书");
                
                System.out.println("* 测试异常: 预期图书不存在，但实际找到了图书 *");
                System.out.println("* 图书ID: " + nonExistentId + " *");
                System.out.println("* 图书标题: " + book.getTitle() + " *");
            }
        } catch (Exception e) {
            Map<String, String> errorInfo = new HashMap<>();
            errorInfo.put("error", e.getMessage());
            errorInfo.put("id", String.valueOf(nonExistentId));
            errorInfo.put("exceptionType", e.getClass().getSimpleName());
            result.put("book", errorInfo);
            result.put("status", "error");
            
            // 在控制台打印详细的异常信息
            System.out.println("* 测试成功: 捕获到预期的异常 *");
            System.out.println("* 异常信息: " + e.getMessage() + " *");
            System.out.println("* 异常类型: " + e.getClass().getName() + " *");
            System.out.println("* 图书ID: " + nonExistentId + " *");
            e.printStackTrace(); // 打印完整堆栈信息
        }
        
        return result;
    }
} 